﻿Imports System.Xml

Namespace Objects

    Public Class DocumentRij

        Private _document As PrintFairShopDocument
        Private _cellen As List(Of DocumentCel)
        Private _hoogteEenheden As Integer

        Private _lefts As List(Of Integer) ' lijst met linkerposities van de cellen in 1/100 inch 
        Private _widths As List(Of Integer) ' lijst met breedtes van de cellen in 1/100 inch

#Region "Public property's"

        ''' <summary>
        ''' Aantal hoogte-eenheden (in fonthoogte) indien de rij een vaste hoogte moet hebben.
        ''' Bv. de waarde 2 wil zeggen dat de rij 2 x fonthoogte hoog is.
        ''' Indien de hoogte zich moet aanpassen aan de inhoud, is de waarde -1
        ''' </summary>
        Public Property HoogteEenheden() As Integer
            Get
                Return _hoogteEenheden
            End Get
            Set(ByVal value As Integer)
                _hoogteEenheden = value
            End Set
        End Property

        Public ReadOnly Property Cellen() As List(Of DocumentCel)
            Get
                Return _cellen
            End Get
        End Property

#End Region

#Region "Constructor/initialisatie"

        Public Sub New(ByVal document As PrintFairShopDocument, ByVal rijNode As XmlNode)
            If (rijNode Is Nothing) Then Throw New Exception("Rij niet gevonden")

            _document = document

            _lefts = New List(Of Integer)
            _widths = New List(Of Integer)

            _cellen = New List(Of DocumentCel)

            Dim celNodes As XmlNodeList = rijNode.SelectNodes("cellen/cel")
            For Each celNode As XmlNode In celNodes
                Dim documentCel As New DocumentCel(celNode, _document.Font)
                _cellen.Add(documentCel)
            Next

            GetVerdelingVanCellen()

            Dim hoogteAttribuut As XmlAttribute = rijNode.Attributes("height")
            If (hoogteAttribuut IsNot Nothing AndAlso hoogteAttribuut.Value <> "auto") Then
                _hoogteEenheden = Convert.ToInt32(hoogteAttribuut.Value)
            Else
                _hoogteEenheden = -1
            End If
        End Sub

#End Region

#Region "Public methods"

        ''' <summary>
        ''' Methode om een rij af te drukken. Veronderstelt dat de tekst al ingesteld is
        ''' </summary>
        ''' <param name="top"></param>
        ''' <param name="gdiPage"></param>
        ''' <returns>Verticale positie van de volgende regel op het blad</returns>
        Public Function Print(ByVal top As Integer, ByVal gdiPage As Graphics) As Integer
            If (_document Is Nothing) Then Return top ' bijvoorbeeld bij titelrij in PrintTicketDocument
            Dim hoogte As Integer = BerekenHoogteVanRij(_document.Font, gdiPage)
            For i As Integer = 0 To _cellen.Count - 1
                Dim cel As DocumentCel = _cellen(i)
                cel.Print(_lefts(i), top, _widths(i), hoogte, gdiPage)
            Next
            Return top + hoogte
        End Function

        Public Sub SetCelTekst(ByVal id As String, ByVal tekst As String)
            For Each cel As DocumentCel In _cellen
                If (cel.ID = id) Then
                    cel.Tekst = tekst
                    Return
                End If
            Next
            Throw New Exception(String.Format("Cel met id {0} niet gevonden", id))
        End Sub

        ''' <summary>
        ''' Zet de waarde van currency in de cel en toont deze in het rood als ze negatief is
        ''' </summary>
        ''' <param name="id"></param>
        ''' <param name="currency"></param>
        Public Sub SetCelCurrency(ByVal id As String, ByVal currency As Decimal)
            For Each cel As DocumentCel In _cellen
                If (cel.ID = id) Then
                    If (currency = 0D) Then
                        cel.Tekst = ""
                    Else
                        cel.Tekst = currency.ToString("N2")
                    End If
                    If (currency < 0) Then
                        cel.ForegroundColor = Brushes.Red
                    Else
                        cel.ForegroundColor = Brushes.Black
                    End If
                    Return
                End If
            Next
            Throw New Exception(String.Format("Cel met id {0} niet gevonden", id))
        End Sub

#End Region

#Region "Private methods"

        Private Sub GetVerdelingVanCellen()
            Dim relatieveBreedtes As New List(Of Single) ' in %
            For Each cel As DocumentCel In _cellen
                If (cel.WidthPercent < 0) Then
                    relatieveBreedtes.Add(100)
                Else
                    relatieveBreedtes.Add(cel.WidthPercent)
                End If
            Next
            Dim totaalRelatieveBreedtes As Single = relatieveBreedtes.Sum()
            If (totaalRelatieveBreedtes > 100) Then
                Throw New Exception("Fout in het printsjabloon: totale breedte groter dan 100%")
            End If
            ' vul aan tot totaal 100
            If (totaalRelatieveBreedtes < 100) Then relatieveBreedtes.Add(100 - totaalRelatieveBreedtes)
            Dim currentLeft As Integer = _document.LeftMargin
            For Each deel As Integer In relatieveBreedtes
                _lefts.Add(currentLeft)
                Dim currentWidth As Integer = Convert.ToInt32(Math.Round((_document.PrintableWidth * deel) / 100))
                _widths.Add(currentWidth)
                currentLeft += currentWidth
            Next
        End Sub

        ''' <summary>
        ''' Bereken de hoogte van een rij
        ''' </summary>
        ''' <param name="defaultFont"></param>
        ''' <param name="gdiPage"></param>
        ''' <returns></returns>
        Private Function BerekenHoogteVanRij(ByVal defaultFont As Font, ByVal gdiPage As Graphics) As Integer
            If (_hoogteEenheden >= 0) Then
                ' absolute hoogte instellen ten opzichte van gebruikte font
                Return _hoogteEenheden * defaultFont.Height
            End If

            ' hoogte is niet vast ingesteld, zoek de hoogte nodig om alle cellen te kunnen tekenen zonder clipping
            Dim hoogte As Integer = defaultFont.Height
            For i As Integer = 0 To _cellen.Count - 1
                Dim cel As DocumentCel = _cellen(i)
                If (cel.Tekst <> "") Then
                    Dim dezeHoogte As Integer = cel.BerekenTekstHoogte(_widths(i), gdiPage)
                    If (dezeHoogte > hoogte) Then hoogte = dezeHoogte
                End If
                If (cel.Afbeelding IsNot Nothing) Then
                    Dim img As Image = cel.Afbeelding
                    Dim imageHoogte As Integer = img.Height * _widths(i) \ img.Width
                    If (imageHoogte > hoogte) Then hoogte = imageHoogte
                End If
            Next
            Return hoogte
        End Function

#End Region

    End Class

End Namespace
